//: [Previous](@previous)

import Foundation

//: ## if-else
// if后面的条件不需要小括号
// 条件之后的大扩后不可以省略
// if后面的条件只能是Bool类型,和oc不一样,oc是非0就行
let age = 4
if age >= 22 {
    print("大于")
} else if age >= 18 {
    print("大于18")
} else {
    print("else")
}
//: ## while
var num = 5
while num > 5 {//先执行print,再-.其实就是直接来个执行多少次
    print("num is \(num)")
    num -= 1
} //会打印5次

// repeat(重复) - while,相当于oc的do-while
var num1 = -1
repeat {//先执行print,再判断大括号外的条件,假如成立继续,不成立停止
    print("num1 is \(num1)")
} while num1 > 0 //打印1次
//: ## for
//: ### 闭区间运算符:a...b,意思是 a <= 取值 <=b
let names = ["00", "11", "22", "33"]

for i in 0...3 {
    print(names[i]) //i:0 1 2 3
} // 输出"00", "11", "22", "33"

let range = 1...3
for j in range {
    print(names[j])
} // 输出 "11", "22", "33"

// i默认是let,有需要时可以声明为var
for var i in 1...3 {
    print(names[i])
} // 输出 "11", "22", "33"
//: ### 半开区间运算符: a..<b, 意思是a <= 取值 < b
for i in 1..<3 {
    print(names[i]) // 1 2
} // 输出 11 22
//: ### 单侧区间:让区间朝一个方向尽可能的远
for name in names[2...] {
    print(name)
}// 输出 22 33

for name in names[...2] {
    print(name)
}// 00 11 22

for name in names[..<2] {
    print(name)
}// 00 11

let range1 = ...5
range1.contains(7) // false
range1.contains(4) // true
range1.contains(-3) // true
//: ## 区间范围
let range1: ClosedRange<Int> = 1...3 //闭区间,双边包含
let range2: Range<Int> = 1..<3 //半开区间,一边不包含
let range3: PartialRangeThrough<Int> = ...5 //单侧区间,一边无穷

// 字符,字符串也能使用区间预算符,但默认不能用在for-in中
let stringRange1 = "cc"..."ff" // ClosedRange<String>
stringRange1.contains("cb") // false
stringRange1.contains("cd") // true
// 从 \0 到 ~ 囊括了所有可能要用到的ASCII字符
let characterRange: ClosedRange<Character> = "\0"..."~"
characterRange.contains("G") // true
// 带间隔的区间值
let housr = 10
let hourInerval = 2
//tickMark的取值:从4开始,累加2,不超过11
//from:开始 through:结束 by:累加值
for tickMark in stride (from: 4, through: housr, by: hourInerval) {
    print(tickMark)
} // 输出 4 6 8 10

//: ## switch

//case,default 后面不能写大括号{}
let number = 1
switch number {
case 1:
    print("1")
    break
case 2:
    print("2")
    break
default:
    print("number is other")
    break
}// 1
//默认可以不写break,并不会贯穿到后面的条件
var number2 = 2
switch number2 {
case 1:
    print("1")
case 2:
    print("2")
default:
    print("other")
}
//fallthrough
//使用fallthrough可以实行贯穿效果,就是oc的Switch中没有写break的效果
var number3 = 1
switch number3 {
case 1:
    print("1")
    fallthrougth
case 2:
    print("2")
default:
    break
}//输出1 2,因为1的时候正常输出,但是有fallthrough,所以哪怕number3是1,还是会跳到吓一跳语句执行了case2的
//: ### 注意点
// 1. Switch 必须要保证能处理所有的情况
var number4 = 1
switch number4 {
case 1:
    print("1")
case 2:
    print("2")
}
 //这段代码是错的,会被系统提示需要处理所有情况.因为number4是整型数字,有无限种可能,现在只判断了两种,所以要加一个default
// 2. default和cese后面必须最少有一条语句.如果不想做任何事情,加个break即可
var number4 = 1
switch number4 {
case 1:
    print("1")
case 2:
    print("2")
default:
    break
}
// 3. 如果能保证处理了所有的情况,那么也可以不加default
enum Answer {case right, wrong}
let answer = Answer.right
switch answer {
case Answer.right
    print("right")
case Answer.wrong
    print("wrong")
}
//: ### 复合条件
// 4. switch 也支持character,string类型
let string = "luo"
switch string {
case "luo":
    fallthrough
case "zhenhao":
    print("真帅")
default:
    break
}// 因为luo那层case有fallthrough贯穿,所以不管string是luo或者是zhenhao,都会输出真帅.达成这个效果
//复合条件有更高级的写法,在case后面用逗号隔开条件即可
let string = "luo"
switch string {
case "luo","zhenhao":
    print("真帅")
default:
    break
}
// 字符
let character: Character = "a"
switch character {
case "a","A":
    print("AAAAAAA")
default:
    print("not AAAAAAA")
}
// 区间匹配,元祖匹配
let count = 62
switch count {
case 0:
    print("none")
case 1..<5:
    print("1-5")
case 5..<12:
    print("5-12")
default:
    print("other")
} // other

let point = (1, 1)
switch point {
case (0, 0):
    print("在原点")
case (_, 0):
    print("在X轴")
case (0, _):
    print("在Y轴")
case (-2...2, -2...2):
    print("在方盒子里面")
default:
    print("不在方盒子里面")
} // 在方盒子内
// 可以使用下划线_来代表忽略的某个值

// 值绑定
// 比如这种元祖的,在case里面的新建的值,x和y,其中有一个能匹配上point1,就会匹配成功,另一个值会赋值上去
let point1 = (2, 0)
switch point1 {
case (let x, 0) :
    print("在x轴上的点,值是\(x)")
case (0, let y):
    print("在y轴上的点,值是\(y)")
case (let x, let y):
    print("else at (\(x),\(y))")
} //在x轴上的点,值是2
// 必要时,let也可以改成var
//: ### switch中加上where的判断条件
let point2 = (1, -1)
switch point2 {
case let (x, y) where x == y:
    print("x == y")
case let (x, y) where x == -y:
    print("x == -y")
case (x, y):
    break
} //x == -y
// 因为直接let (x, y),2个都没有限制条件,所以会直接赋值point2的值,但是,后面where的判断条件需要成立才可以进入case的执行语句

// where不仅可以用在Switch里面,还可以用在for循环里面
var numberArr = [10, -10, 20, -20, 30, -30]
var sum = 0
for number in numberArr where number > 0{// 使用where过滤number,达到只有大于0的元素才可以进到循环的作用
    sum += number
}// 10 + 20 + 30 = 60
// 注意这个where是过滤的意思,不是停止此循环.意思就是满足where的条件,就可以正常进入循环里面的执行语句,不满足只是此次循环不进入执行语句而已,不是说会因此停止循环
//: ## 标签语句
//outer,
outer: for i in 1...4 {
    for j in 1...3 {
        if j == 3 {
            //继续
            continue outer
        }
        
        if i == 3 {
            break outer
        }
        
        print("\(i),\(j)")
    }
}
//outer用作标签去修饰了外层的for循环,正常情况下假如没有这个outer,里面这个for循环continue和break的时候都是影响了里面这个for循环,这样子在里面的for循环的执行语句后面加上outer,代码就知道此时操作的是外循环






//: [Next](@next)
